package fm.mongoService.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.tencent.common.MD5;
import fm.cache.AreaCache;
import fm.cache.ConfigCache;
import fm.dao.HibernateBaseDao;
import fm.dao.MongoBaseDao;
import fm.dto.NeiyiUser;
import fm.dto.SystemUser;
import fm.dto.NeiyiUser;
import fm.entity.Address;
import fm.entityEnum.ActionTypeEnum;
import fm.entityEnum.CarouselType;
import fm.exception.BizException;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.mongo.MongoTable;
import fm.mongoService.UserService;
import fm.util.CommonUtils;
import fm.util.DateUtils;
import fm.web.CurrentRequest;
import freemarker.template.utility.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;

/**
 * Created by 61741 on 2018/1/8.
 */
@Service
public class UserServiceImpl implements UserService {
    private final static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    MongoBaseDao mongoBaseDao;
    @Autowired
    HibernateBaseDao baseDao;

    @Override
    public List<NeiyiUser> getUserPage(Integer pageSize, Integer pageSite, Map params, Map sort) {
        return null;
    }

    @Override
    public void addUser(NeiyiUser user) throws Exception {
        user.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        mongoBaseDao.insert(user, MongoTable.user);
    }

    @Override
    public List<NeiyiUser> getByTypeAndUserId(Map params, Integer pageSize, Integer pageNum, String sort) throws Exception {
        DBObject sortby = new BasicDBObject("regTime", Sort.Direction.DESC.toString());
        if (!StringUtils.isEmpty(sort)) {
            sortby.put(sort, Sort.Direction.DESC.toString());
        }

        if (pageNum != null && pageSize != null) {
            return (List<NeiyiUser>) mongoBaseDao.getPageList(params, NeiyiUser.class, pageSize, pageNum, MongoTable.user, sortby);
        } else {
            return (List<NeiyiUser>) mongoBaseDao.getList(params, NeiyiUser.class, MongoTable.user, sortby);
        }
    }

    @Override
    public long countUser(Map params) {
        return mongoBaseDao.count(params, MongoTable.user);
    }

    @Override
    public int insertUserbyExcel(List<Map<String, Object>> list, Integer userType) {
        int cont = 0;
        if (list.isEmpty()) {
            throw new BizException("文件为空请重新上传!");
        }
        for (Map<String, Object> item : list.subList(1, list.size())) {
            try {
                if (CommonUtils.isEmpty(item)) {
                    continue;
                }

                NeiyiUser user = new NeiyiUser();
                user.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                user.setPhone(item.get("value1") + "");
                user.setUserType(userType);
                user.setCompanyName((String) item.get("value2"));


                Address province = AreaCache.getAddressByShortName((String) item.get("value3"));
                Address city = AreaCache.getAddressByShortName((String) item.get("value4"));
                Address town = AreaCache.getAddressByShortName((String) item.get("value5"));
                user.setUserAdd(CommonUtils.isEmpty(city) ? "" : city.getAddressId(), CommonUtils.isEmpty(province) ? "" : province.getAddressId(), CommonUtils.isEmpty(town) ? "" : town.getAddressId(), (String) item.get("value6"));
                user.setUserAddressName(CommonUtils.isEmpty(province) ? "" : province.getName(), CommonUtils.isEmpty(city) ? "" : city.getName(), CommonUtils.isEmpty(town) ? "" : town.getName());
                user.setUserContact((String) item.get("value7"));
                user.setUserDsc((String) item.get("value8"));
                user.setMajarbus((String) item.get("value9"));
                user.setChairtMan((String) item.get("value10"));
                user.setBusCity((String) item.get("value11"));
                user.setStName((String) item.get("value12"));
                user.setReviewStatus(1);
                user.setReviewNote("");
                user.setRemark("批量导入");
                user.setRegTime(new Date());
                user.setRegType("3");
                user.setUserLogo("");
                user.setBusListenerPic("");
                user.setIdCardImg1("");
                user.setIdCardImg2("");
                user.setCompanyPics(new ArrayList<>());
                user.setFlags(new ArrayList<>());
                user.setTopLevel(0);
                user.setFirstUpdate(0);
                try {
                    mongoBaseDao.insert(user, "user");
                } catch (Exception e) {
                    LOGGER.error("倒入数据发生错误", e);
                }
                cont++;
            } catch (Exception ex) {
                LOGGER.error("用户导入错误:{}", JSON.toJSONString(item), ex);
            }
        }
        return cont;
    }

    @Override
    public NeiyiUser getUserAuthInfo(String userId) {
        Map params = new HashMap<>();
        params.put("_id", userId);
        LOGGER.info(userId);
        NeiyiUser user = (NeiyiUser) mongoBaseDao.findOne(params, NeiyiUser.class, MongoTable.user);
        LOGGER.info(JSON.toJSONString(user));
        if (user == null) {
            throw new BizException("未找到相关用户信息，获取认证资料失败！");
        }
        Integer userType = Integer.parseInt(user.getUserType().toString());
        String table = null;
        switch (userType) {
            case 1:
                throw new BizException("普通用户没有认证资料!");
            case 2:
            case 3:
            case 4:
            case 5:
                if (Integer.parseInt(user.getReviewStatus().toString()) == 0) {
                    throw new BizException("用户尚未提交认证资料！");
                }
                table = MongoTable.engineer_auth_info;
                break;
            default:
                throw new BizException("未知的用户类型，认证资料获取失败!");
        }
        return user;
    }

    /**
     * 更新user表数据
     *
     * @param queryParam
     * @param updateItem
     * @return
     */
    @Override
    public int updateUserInfo(Map queryParam, Map updateItem) {
        LOGGER.info("update user info :{},{}", JSON.toJSONString(queryParam), JSON.toJSONString(updateItem));
        int updateCount = mongoBaseDao.updateOne(queryParam, updateItem, MongoTable.user);
        return updateCount;
    }

    @Override
    public int updateUserInfo(Map query, SystemUser user) {
        Map hashMap = new HashMap();
        String userJson = JSON.toJSONString(user);
        hashMap.putAll(JSON.parseObject(userJson));

        return updateUserInfo(query, hashMap);
    }

    @Override
    public boolean checkSms(String phone, String smsCode) throws Exception {
        if (phone.equals("18359219330") && smsCode.equals("CMStudio18")) {
            return true;
        }
        MCondition mc = MCondition.create(MRel.and);
        mc.append("phone", phone);
        mc.append("type", ActionTypeEnum.LOGIN_VERIFY.toString());
        mc.append("check_status", 0);
        mc.append(MCondition.create(MRel.lte).append("latm", new Date()));
        mc.append(MCondition.create(MRel.gte).append("latm", DateUtils.addMinute(new Date(), -30)));

        List<DBObject> items = (List<DBObject>) mongoBaseDao.getPageList(mc.toDBObject().toMap(), DBObject.class, 1, 1, MongoTable.sms_log, new BasicDBObject("latm", Sort.Direction.DESC.toString()));
        if (CollectionUtils.isEmpty(items)) {
            throw new BizException("短信验证码无效");
        }

        boolean result = String.valueOf(items.get(0).get("content")).equals(smsCode);
        if (result == true) {
            mongoBaseDao.updateOne(mc.toDBObject().toMap(), new BasicDBObject("check_status", 1).toMap(), MongoTable.sms_log);
        }
        return result;
    }

    @Override
    public boolean checkPass(String userName, String password) throws Exception {
        String adminUserName = ConfigCache.getConfig("ADMIN_USER_NAME", "18359219330");
        String adminUSerPass = ConfigCache.getConfig("ADMIN_USER_PASS", "25114A7E5F08ABD707907C8C1ECB84EB");
        LOGGER.info("adminUserPasswrod:{}", MD5.MD5Encode(password));

        return adminUserName.equals(userName) && adminUSerPass.equals(MD5.MD5Encode(password).toUpperCase());
    }

    @Override
    public NeiyiUser getUserByPhone(String phone) {
        DBObject queryCondition = new BasicDBObject("phone", phone);
        return (NeiyiUser) mongoBaseDao.findOne(queryCondition.toMap(), NeiyiUser.class, MongoTable.user);
    }

    @Override
    public NeiyiUser getById(String phone) {
        return (NeiyiUser) mongoBaseDao.findOne(new BasicDBObject("id", phone).toMap(), NeiyiUser.class, MongoTable.user);
    }

    @Override
    public NeiyiUser getUserByOpenId(String openid) {

        return (NeiyiUser) mongoBaseDao.findOne(new BasicDBObject("openid", openid).toMap(), NeiyiUser.class, MongoTable.user);
    }

    @Override
    public NeiyiUser getUserByUnionid(String unionid) {
        return (NeiyiUser) mongoBaseDao.findOne(new BasicDBObject("unionid", unionid).toMap(), NeiyiUser.class, MongoTable.user);
    }

    @Override
    public List<NeiyiUser> getAllMerchantUser() throws Exception {
        return (List<NeiyiUser>) mongoBaseDao.getList(MCondition.create(MRel.gt).append("regType", "1").toDBObject().toMap(), NeiyiUser.class, MongoTable.user);
    }

    @Override
    public List<NeiyiUser> getUserList(Integer userType, String keyword) throws Exception {
        if (CommonUtils.isEmpty(userType) && CommonUtils.isEmpty(keyword)) {
            Map<String,Object> param = new HashedMap();
            int[] arr = {2,3,4,5};
            MCondition mc = MCondition.create(MRel.in);
            mc.append("userType", arr);
            return (List<NeiyiUser>) mongoBaseDao.getList(mc.toDBObject().toMap(), NeiyiUser.class,MongoTable.user);
        }
        MCondition mc = MCondition.create(MRel.and);
        if (!CommonUtils.isEmpty(userType)) {
            mc.append(MCondition.create(MRel.or).append("userType", userType).append("userType", userType + ""));
        }
        if (!CommonUtils.isEmpty(keyword)) {
            mc.append(MCondition.create(MRel.regex).append("companyName", keyword));
        }

        return (List<NeiyiUser>) mongoBaseDao.getList(mc.toDBObject().toMap(), NeiyiUser.class, MongoTable.user);
    }
    @Override
    public List<NeiyiUser> getUserPageList(Integer userType, String keyword, Integer pageSize, Integer pageNum) throws Exception {
        if (CommonUtils.isEmpty(userType) && CommonUtils.isEmpty(keyword)) {
            Map<String,Object> param = new HashedMap();
            int[] arr = {2,3,4,5};
            MCondition mc = MCondition.create(MRel.in);
            mc.append("userType", arr);
            return (List<NeiyiUser>) mongoBaseDao.getPageList(mc.toDBObject().toMap(), NeiyiUser.class,pageSize,pageNum,MongoTable.user);
        }
        MCondition mc = MCondition.create(MRel.and);
        if (!CommonUtils.isEmpty(userType)) {
            mc.append(MCondition.create(MRel.or).append("userType", userType).append("userType", userType + ""));
        }
        if (!CommonUtils.isEmpty(keyword)) {
            mc.append(MCondition.create(MRel.regex).append("companyName", keyword));
        }

        return (List<NeiyiUser>) mongoBaseDao.getPageList(mc.toDBObject().toMap(), NeiyiUser.class,pageSize,pageNum,MongoTable.user);
    }

    @Override
    public List<DBObject> getCarouselListByUserId(CarouselType type, String shopId) throws Exception {
        MCondition mc = MCondition.create(MRel.and);
        if (type != null) {
            mc.append("type", type.toString());
        }
        if (CommonUtils.isEmpty(shopId)) {
            mc.append("user_id", CurrentRequest.getCurrentUserId());
        } else {
            mc.append("user_id", shopId);
        }
        return (List<DBObject>) mongoBaseDao.getList(mc.toDBObject().toMap(), DBObject.class, MongoTable.shop_carousel);
    }

    @Override
    public void InserApplayInfo(String name, String phone) throws Exception {
        Map param = new HashMap();
        param.put("name",name);
        param.put("phone",phone);
        param.put("statu",0);
        param.put("regTime",new Date());
        mongoBaseDao.insert(param,MongoTable.applay_info);
    }

    @Override
    public void deleteApplayInfo(String phone) throws Exception {
        Map param = new HashMap();
        param.put("phone",phone);

        mongoBaseDao.delete(param,MongoTable.applay_info);
    }

    @Override
    public void deleteUserById(String id) throws Exception {
        Map param = new HashMap();
        param.put("_id",id);
        mongoBaseDao.delete(param,MongoTable.user);
    }

    @Override
    public void updateApplayInfo(String phone) throws Exception {
        Map param = new HashMap();
        param.put("phone",phone);
        Map update = new HashMap();
        update.put("statu",1);
        mongoBaseDao.updateOne(param,update,MongoTable.applay_info);
    }

    @Override
    public List<DBObject> getApplayList(Integer pageNum,Integer pageSize) throws Exception {
        DBObject sortby = new BasicDBObject("regTime", Sort.Direction.DESC.toString());
        Map param = new HashMap();
       List<DBObject> applayList = (List<DBObject>) mongoBaseDao.getPageList(param,DBObject.class,pageSize,pageNum,MongoTable.applay_info,sortby);
        return applayList;
    }
}
